import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;

import com.thoughtworks.xstream.XStream;

public class boggleMain {

	public static void main(String[] args) {
		//Set Players
		List<player> players = new ArrayList<player>();
		players.add(new player("Gringo"));
		players.add(new player("Potpot"));

		//Set Letters
		List<Character[]> lets = new ArrayList<Character[]>();
		lets.add(new Character[]{'S','E','R','S'});
		lets.add(new Character[]{'P','A','T','G'});
		lets.add(new Character[]{'L','I','N','E'});
		lets.add(new Character[]{'S','E','R','S'});

		//Set Dictionary
		List<String> wordList = new ArrayList<String>();

		//Load Dictionary
		File dictionaryFile;
		JFileChooser chooser = new JFileChooser();
		chooser.setFileFilter(new FileNameExtensionFilter("Text Files", "txt"));
		if(chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION){
			dictionaryFile = chooser.getSelectedFile();

			try {
				Scanner words = new Scanner (dictionaryFile);

				//Checker for empty line
				while(words.hasNextLine()){
					String newWord = words.nextLine().trim();
					if (!(newWord.isEmpty()))
						wordList.add(newWord.toUpperCase());
				}
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

		//Instantiates game with set board
		boggleGame newGame = new boggleGame(lets, wordList, players);

		//		//Instantiates game with random board
		//		boggleGame newGame = new boggleGame(4, wordList, players);

		//		//Load Game
		//		File xmlFile = new File("C:\\Users\\Rommel\\Desktop\\boggleSaveGame.xml");
		//		XStream xstream = new XStream();
		//		boggleGame newGame = (boggleGame)xstream.fromXML(xmlFile);

		//Prints Current Word Stats
		int[] wordStats = newGame.getWordStats();
		System.out.println("Available Words:");
		System.out.println(String.format("3-4 Letters: %d (1 pt)", wordStats[0]));
		System.out.println(String.format("5 Letters: %d (2 pts)", wordStats[1]));
		System.out.println(String.format("6 Letters: %d (3 pts)", wordStats[2]));
		System.out.println(String.format("7 Letters: %d (5 pts)", wordStats[3]));
		System.out.println(String.format("8 Letters: %d (11 pts)", wordStats[4]));
		System.out.println(String.format("9 Letters: %d (2 pts/letter)", wordStats[5]));
		System.out.println(String.format("Total Words: %d", newGame.getExistingWords().size()));
		System.out.println();

		//Prints Current Game Board
		for(Character[] letters: newGame.getCurrentBoard().getLetters()){
			for(Character let : letters){
				System.out.print("[" + let + "]");
			}
			System.out.println();
		}
		System.out.println();

		//Start Game
		int currentPlayer = newGame.getCurrentPlayer();
		Boolean continueGame = true;
		while(currentPlayer < newGame.getPlayers().size() && continueGame){
			System.out.print(String.format("Current Player: %s", newGame.getPlayers().get(currentPlayer).getName()));
			System.out.println();

			//Player guesses words
			for(int i = 0; i<5 && continueGame; i++){
				String guess = new Scanner(System.in).next();
				//Save Game
				if(guess.equals("!savegame")){
					newGame.saveGame("C:\\Users\\Rommel\\Desktop\\boggleSaveGame.xml");
					continueGame = false;
				}
				//The highlighter of letters
				//				else if(guess.length() == newGame.getCurrentBoard().wordExists(guess, true)){
				//					Boolean[][] passedLetters = newGame.getCurrentBoard().getPassedLetters();
				//					for(int x = 0; x < newGame.getCurrentBoard().getLetters().size(); x++){
				//						for(int y = 0; y < newGame.getCurrentBoard().getLetters().size(); y++){
				//							System.out.print("[" + (passedLetters[x][y] ? "1" : "0") + "]");
				//						}
				//						System.out.println();
				//					}
				//					System.out.println();
				//				}
				else{
					while(guess.length() < 3 || newGame.getPlayers().get(currentPlayer).wordGuessed(guess) || newGame.getCurrentBoard().wordExists(guess, false) != guess.length()){
						if(guess.length() < 3)
							System.out.println("Must be 3+ letters long");
						else if(newGame.getPlayers().get(currentPlayer).wordGuessed(guess))
							System.out.println("Word already guessed");
						else if(newGame.getCurrentBoard().wordExists(guess, false) != guess.length()){
							System.out.println("No such combination exists on board");
						}
						guess = new Scanner(System.in).next();
					}
					newGame.getPlayers().get(currentPlayer).addGuessedWord(guess);
				}
			}

			System.out.println();
			currentPlayer++;
			newGame.setCurrentPlayer(currentPlayer);
		}

		//Generate results
		System.out.println("<========== Results ==========>");
		newGame.generateResults();
		//Prints common words
		System.out.println("<===== Common Words =====>");
		for(String word : newGame.getCommonWords()){
			System.out.println(word);
		}
		System.out.println();
		for(player play : newGame.getPlayers()){
			System.out.println(String.format("<===== %s =====>\n",play.getName()));

			//Prints accepted words
			System.out.println("Accepted Words:");
			for(String word : play.getAcceptedWords()){
				System.out.println(word);
			}
			System.out.println();

			//Prints unaccepted words
			System.out.println("Unaccepted Words:");
			List<String> unacceptedWords = new ArrayList<String>();
			unacceptedWords.addAll(play.getGuessedWords());
			unacceptedWords.removeAll(play.getAcceptedWords());
			unacceptedWords.removeAll(newGame.getCommonWords());
			for(String word : unacceptedWords){
				System.out.println(word);
			}
			System.out.println();

			//Prints Stats
			System.out.println("Stats:");
			int[][] stats = play.getStats();
			System.out.println(String.format("3-4 Letter Words: %d x 1pt = %d", stats[0][0], stats[1][0]));
			System.out.println(String.format("5 Letter Words: %d x 2pts = %d", stats[0][1], stats[1][1]));
			System.out.println(String.format("6 Letter Words: %d x 3pts = %d", stats[0][2], stats[1][2]));
			System.out.println(String.format("7 Letter Words: %d x 5pts = %d", stats[0][3], stats[1][3]));
			System.out.println(String.format("8 Letter Words: %d x 11pts = %d", stats[0][4], stats[1][4]));
			System.out.println(String.format("9 Letter Words: %d (2pts/letter) = %d", stats[0][5], stats[1][5]));
			System.out.println();
			System.out.println("Total Accepted Words: " + stats[0][6]);
			System.out.println("Total Score: " + stats[1][6]);
			System.out.println();
		}

		//		//Print existing words
		//		for(String word: newGame.getExistingWords()){
		//			System.out.println(word);
		//		}
		//		System.out.println("Number of Words :  " + newGame.getExistingWords().size());

		//		//Test Performance of Starting new game and getting existing words
		//		{
		//			long testStartTime = System.currentTimeMillis();
		//			
		//			int accurTime = 10;
		//
		//			long avgTime = 0;
		//			long minTime = -1;
		//			long maxTime = -1;
		//			for(int i = 0; i < accurTime; i++){
		//				long totalTime = 0;
		//				long startTime = System.currentTimeMillis();
		//				newGame = new boggleGame(4, "C:\\Users\\Rommel\\Desktop\\wordList.txt");
		//				newGame.getExistingWords();
		//				long endTime = System.currentTimeMillis();
		//				totalTime = endTime - startTime;
		//				if(minTime == -1 || minTime > totalTime){
		//					minTime = totalTime;
		//				}
		//				if(maxTime == -1 || maxTime < totalTime){
		//					maxTime = totalTime;
		//				}
		//				avgTime += totalTime;
		//			}
		//			avgTime /= accurTime;
		//			System.out.println("==========================================");
		//			System.out.println("Performance test out of " + accurTime + " game/s:");
		//			System.out.println("Minimum Time: "  + minTime);
		//			System.out.println("Maximum Time: "  + maxTime);
		//			System.out.println("Average Time :  " + avgTime + " milliseconds");
		//			System.out.println("Total time of performance test: " + ((System.currentTimeMillis() - testStartTime) / 1000) + " seconds");
		//		}

		//		//Word Count Test
		//		{
		//			long startTime = System.currentTimeMillis();
		//			
		//			int accurWords = 10;
		//			
		//			int minWords = -1;
		//			int maxWords = -1;
		//			int avgWords = 0;
		//			boggleGame wordCountTest;
		//
		//			for(int i = 0; i<accurWords; i++){
		//				wordCountTest = new boggleGame(4, "C:\\Users\\Rommel\\Desktop\\wordList.txt");
		//				int wordCounter = wordCountTest.getExistingWords().size();
		//				if (minWords > wordCounter || minWords == -1){
		//					minWords = wordCounter;
		//				}
		//				if (maxWords < wordCounter || maxWords == -1){
		//					maxWords = wordCounter;
		//				}
		//				avgWords += wordCounter;
		//			}
		//			avgWords /= accurWords;
		//
		//			System.out.println("==========================================");
		//			System.out.println("Word count test out of " + accurWords + " game/s:");
		//			System.out.println("Minimum words: "  + minWords);
		//			System.out.println("Maximum words: "  + maxWords);
		//			System.out.println("Average words: " + avgWords);
		//			System.out.println("Total time of word count test: " + ((System.currentTimeMillis() - startTime) / 1000) + " seconds");
		//		}
	}

}
